#ifndef __LINKLIST_HPP_
#define __LINKLIST_HPP_
#include<iostream>

template <typename T>
class LinkList
{
public:
    LinkList();
    void InserTail(const T &element);
    void InsertHead(const T& element);
    void show();

    template <typename T1>
    friend std::ostream& operator<<(std::ostream &os, const LinkList<T1> &list);
private:
    struct Node
    {
        Node(const T &element)
        {
            data = element;
            next = nullptr;
        }
        T data; // 数据域
        Node *next;
    };

    Node *head;
    int size;
};

template <class T>
LinkList<T>::LinkList()
{
    // 模板支持匿名对象来构建对象
    head = new Node(T());
}

template <typename T>
inline void LinkList<T>::InserTail(const T &element)
{
    Node *travelPoint = head;
    while (travelPoint->next != nullptr)
    {
        travelPoint = travelPoint->next;
    }

    travelPoint->next = new Node(element); // 两句合一句
    size++;
}

template <typename T>
inline void LinkList<T>::InsertHead(const T &element)
{
    Node *newNode= new Node(element);
    newNode->next= head->next;
    head->next= newNode;
    size++;
}

template <class T>
void LinkList<T>::show()
{
    std::cout << "size:" << size << std::endl;
    // 遍历指针
    Node *travelPoint = head->next;
    while (travelPoint != nullptr)
    {
        std::cout << travelPoint->data << " ";
        travelPoint = travelPoint->next;
    }
    std::cout << std::endl;
}

#endif

template <typename T1>
inline std::ostream &operator<<(std::ostream &os, const LinkList<T1> &list)
{
    std::cout << "size:" << list.size << std::endl;
    // 遍历指针
    // typename: 专属于模板的关键字 声明后面跟着的模板是一个类型
    typename LinkList<T1>::Node *travelPoint = list.head->next;
    while (travelPoint != nullptr)
    {
        std::cout << travelPoint->data << " ";
        travelPoint = travelPoint->next;
    }
    std::cout << std::endl;
    return os;
}

